<template>
    <canvas @click="changeImgCode" ref="canvasRef" :width="width" :height="height"></canvas>
</template>

<script setup>
import { reactive, defineProps, ref, defineExpose, onMounted, toRef } from 'vue'

const props = defineProps({
    width: {
        type: Number,
        default: 120
    },
    height: {
        type: Number,
        default: 40
    },
    length: {
        type: Number,
        default: 4
    }
})

const state = reactive({
    pool: 'abcdefghijklmnopqrstuvwxyz0123456789',
    imgCode: ''
})

onMounted(() => {
    state.imgCode = createImgCode()
})

// 生成验证码
const canvasRef = ref(null)
const createImgCode = () => {
    // 获取画布
    const ctx = canvasRef.value.getContext('2d')
    // 填充颜色
    ctx.fillStyle = randomColor(180, 220)
    // 填充位置 颜色全填满
    ctx.fillRect(0, 0, props.width, props.height)
    // 填充文字
    let imgCode = ''
    let length = props.length
    for (let i = 0; i < length; i++) {
        const text = state.pool[randomNum(0, state.pool.length)]  //随机取一个字符
        imgCode += text
        const fontSize = randomNum(18, 40)
        const deg = randomNum(-45, 45)
        // 绘制文字
        ctx.font = `${fontSize}px SimHei`
        // 文字顶部对齐
        ctx.textBaseline = 'top'
        // 填充的文字颜色
        ctx.fillStyle = randomColor(80, 160)
        // 保留当前的修改
        ctx.save()
        ctx.translate(30 * i + 15, 15)
        ctx.rotate((Math.PI * deg) / 180)
        ctx.fillText(text, -10, -15)
        // 清楚之前的修改
        ctx.restore()
    }
    // 绘制干扰线
    for (let i = 0; i < 5; i++) {
        ctx.beginPath()
        // 线落笔
        ctx.moveTo(randomNum(0, props.width), randomNum(0, props.height))
        // 线终点
        ctx.lineTo(randomNum(0, props.width), randomNum(0, props.height))
        ctx.strokeStyle = randomNum(180, 230)
        ctx.closePath()
        ctx.stroke()
    }
    // 绘制干扰点
    for (let i = 0; i < 40; i++) {
        ctx.beginPath()
        ctx.arc(randomNum(0, props.width), randomNum(0, props.height), 1, 0, Math.PI * 2)
        ctx.fillStyle = randomColor(150, 200)
        ctx.closePath()
        ctx.fill()
    }
    console.log(imgCode);

    return imgCode
}

// 生成r g b随机值
const randomNum = (min, max) => {
    return parseInt(Math.random() * (max - min) + min)
}

// 生成随机色
const randomColor = (min, max) => {
    const r = randomNum(min, max)
    const g = randomNum(min, max)
    const b = randomNum(min, max)
    return `rgb(${r},${g},${b})`
}

//  刷新验证码
const changeImgCode = () => {
    state.imgCode = createImgCode()
}

// 暴露给父组件
const verifyCode = toRef(state, 'imgCode')
defineExpose({
    verifyCode: verifyCode
})
</script>

<style lang="less" scoped></style>